﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO.Pipes;
using System.Runtime.InteropServices.ComTypes;
using System.Collections;
using System.Collections.ObjectModel;
using System.Globalization;
using Microsoft.VisualBasic.FileIO;

struct gameDirStruct
{
    //定义游戏目录信息结构体
    public string collection;
    public string sortBy;
    public string extensions;
    public string ignoeFile;
    public string launch;
}
struct gameInfoStruct
{
    //定义游戏信息结构体
    public string game;
    public string file;
    public string files;
    // 判断是否是双行file
    public int fileType;
    // 判断媒体文件是按game还是按file记录。
    public int mediaType;
    public string sortBy;
    public string developer;
    public string publisher;
    public string genre;
    public string xID;
    public string box;
    public string logo;
    public string video;
    public string launch;
    public string description;
}

namespace GManager
{
    public partial class Form1 : Form
    {
        //定义公共变量
        //游戏目录gameDirPath
        public static string gameDirPath;
        //txt文件名
        public static string gameTextName = "metadata.pegasus.txt";

        //定义一个存放每一个游戏gameInfoStruct数据体的list
        List<gameInfoStruct> gameList;
        //定义一个存放目录信息的gameDirStruct数据体
        gameDirStruct gameDirStruct;
        //定义存放每条游戏信息的结构体gameInfoStruct
        gameInfoStruct gameInfoStruct;
        //定义存放需要删除的游戏信息的结构体
        List<gameInfoStruct> gameDel;
        //定义一个新的目录选择对话框，在这里定义可以实现记录上次选择目录的效果
        FolderBrowserDialog folderDlg = new FolderBrowserDialog();

        public Form1()
        {
            InitializeComponent();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //目录信息【修改】按钮
            MessageBox.Show("这道题我还不会！", "略略~");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            //游戏列表【保存】按钮
            //修改前警告
            var i = MessageBox.Show("铛铛！\n确定要保存当前的列表吗？", "警告[○･｀Д´･ ○]", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (i != DialogResult.OK)
            {
                return;
            }

            //备份文件
            if (CopyFile(gameDirPath + "\\" + gameTextName) != 1) 
            {
                MessageBox.Show("备份文件失败！保存进程终止！", "咳咳！");
                return;
            }

            //生成新的内容
            StreamWriter sw = new StreamWriter(gameDirPath + "\\" + gameTextName);

            if(gameDirStruct.collection != null) sw.WriteLine("collection:" + gameDirStruct.collection);
            if (gameDirStruct.sortBy != null) sw.WriteLine("sort-by:" + gameDirStruct.sortBy);
            if (gameDirStruct.extensions != null) sw.WriteLine("extensions:" + gameDirStruct.extensions);
            if (gameDirStruct.ignoeFile != null) sw.WriteLine("ignore-files:\n" + gameDirStruct.ignoeFile.Replace("|", "\n"));
            if (gameDirStruct.launch != null) sw.WriteLine("launch:" + gameDirStruct.launch + "\n");

            //MessageBox.Show(gameList[0].files.Length.ToString(), "咳咳！");
            for (int ii = 0; ii <= gameList.Count - 1; ii++)
            {
                if (gameList[ii].game != null) sw.WriteLine("game:" + gameList[ii].game);
                if (gameList[ii].file != null) sw.WriteLine("file:" + gameList[ii].file);
                if (gameList[ii].files != null) sw.WriteLine("files:\n" + gameList[ii].files);
                if (gameList[ii].sortBy != null)
                {
                    // 如果选择了重排，则输出重排后的序号。
                    if (checkBox2.Checked == true) sw.WriteLine("sort-by:" + " " + (ii + 1).ToString().PadLeft(3, '0'));
                    else sw.WriteLine("sort-by:" + gameList[ii].sortBy);
                }
                if (gameList[ii].developer != null) sw.WriteLine("developer:" + gameList[ii].developer);
                if (gameList[ii].publisher != null) sw.WriteLine("publisher:" + gameList[ii].publisher);
                if (gameList[ii].genre != null) sw.WriteLine("genre:" + gameList[ii].genre);
                if (gameList[ii].xID != null) sw.WriteLine("x-id:" + gameList[ii].xID);
                if (gameList[ii].box != null) sw.WriteLine("assets.box_front:" + gameList[ii].box);
                if (gameList[ii].logo != null) sw.WriteLine("assets.logo:" + gameList[ii].logo);
                if (gameList[ii].video != null) sw.WriteLine("assets.video:" + gameList[ii].video);
                if (gameList[ii].launch != null) sw.WriteLine("launch:" + gameList[ii].launch);
                if (gameList[ii].description != null) sw.WriteLine("description:" + gameList[ii].description + "\n");
            }

            // 关闭文件
            sw.Close();

            // 删除文件
            if (checkBox1.Checked == true) 
            {
                for (int iii = 0; iii <= gameDel.Count - 1; iii++)
                {
                    // 得到游戏媒体目录名称
                    string deldir;
                    switch (gameDel[iii].mediaType)
                    {
                        case 1:
                            // 以单行file文件作为媒体文件夹名字
                            deldir = KillLast(gameDel[iii].file);
                            break;
                        case 2:
                            // 以game为媒体文件夹名字
                            deldir = gameDel[iii].game.Trim();
                            break;
                        default:
                            // 都不是，就乱安一个没有的名字
                            deldir = "这游戏就没有media文件夹";
                            break;
                    }

                    try
                    {
                        // 删除媒体文件夹到回收站
                        if (Directory.Exists(gameDirPath + "\\media\\" + deldir))
                        {
                            FileSystem.DeleteDirectory(gameDirPath + "\\media\\" + deldir, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                        }
                        else
                        {
                            // 删除媒体文件到回收站
                            if (gameDel[iii].box != null && File.Exists(gameDirPath + "\\" + gameDel[iii].box.Trim())) FileSystem.DeleteFile(gameDirPath + "\\" + gameDel[iii].box.Trim(), UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                            if (gameDel[iii].logo != null && File.Exists(gameDirPath + "\\" + gameDel[iii].logo.Trim())) FileSystem.DeleteFile(gameDirPath + "\\" + gameDel[iii].logo.Trim(), UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                            if (gameDel[iii].video != null && File.Exists(gameDirPath + "\\" + gameDel[iii].video.Trim())) FileSystem.DeleteFile(gameDirPath + "\\" + gameDel[iii].video.Trim(), UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                        }
                    }
                    catch (FileNotFoundException ex)
                    {
                        // 提示删除失败
                        MessageBox.Show("媒体文件删除失败！\n" + ex, "咳咳！");
                    }

                    // 开始删除文件
                    if (gameDel[iii].fileType != 1)
                    {
                        try
                        {
                            // file单行时
                            if (File.Exists(gameDirPath + "\\" + gameDel[iii].file.Trim())) FileSystem.DeleteFile(gameDirPath + "\\" + gameDel[iii].file.Trim(), UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);

                        }
                        catch (FileNotFoundException ex)
                        {
                            // 提示删除失败
                            MessageBox.Show("游戏文件删除失败！\n" + ex, "咳咳！");
                        }

                    }
                    else 
                    {
                        try
                        {
                            // files为多行时，把"/"替换成"\\"，并把files分割成多行
                            var xdir = gameDel[iii].files.Replace("\\", "/").Split('\n');
                            //判断游戏文件夹是否存在，若存在则删除整个文件夹，若不存在，则逐个删除游戏文件。
                            string tdir1 = gameDirPath + "\\";
                            if (xdir[0].LastIndexOf("/") != -1) 
                            {
                                tdir1 += xdir[0].Substring(0, xdir[0].LastIndexOf("/")).Trim().Replace("/", "\\");
                            }else tdir1 += xdir[0].Trim();

                            if (Directory.Exists(tdir1)) 
                            { 
                                FileSystem.DeleteDirectory(tdir1, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); 
                            }
                            else 
                            { 
                                foreach (var x in xdir) 
                                {
                                    //逐行删除文件
                                    if (File.Exists(gameDirPath + "\\" + x.Trim())) FileSystem.DeleteFile(gameDirPath + "\\" + x.Trim(), UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                                }
                            }
                            
                        }
                        catch (FileNotFoundException ex)
                        {
                            // 提示删除失败
                            MessageBox.Show("游戏文件删除失败！\n" + ex, "咳咳！");
                        }
                    }
                }
            }

            // 删除列表归零，重新加载目录
            gameDel.Clear();
            OutToListBox();

        }

        private void button3_Click(object sender, EventArgs e)
        {
            //游戏列表【修改】按钮
            MessageBox.Show("这是至尊会员才能使用的专属按钮，它比其他按钮更大更尊贵，请不要乱点！", "咳咳！");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //目录信息【打开】按钮

            //打开选择目录对话框
            
            folderDlg.ShowDialog();
            string gamePath = folderDlg.SelectedPath;

            //开始加载
            LoadText(gamePath, gameTextName);

            //重启程序
            //var i = MessageBox.Show("铛铛！\n这是一个一次性按钮，想要再次使用就必须关闭程序再打开！\n要重启程序吗？", "警告[○･｀Д´･ ○]", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            //if (i == DialogResult.OK) 
            //{
            //    //重启程序
            //    Application.Exit();
            //    System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
            //}

        }

        #region  预载函数
        public void LoadText(string gamePath, string textName)
        {
            //载入Text文件的函数

            //读取文本，不存在则报错
            StreamReader readerText = null;
            if (File.Exists(gamePath + "\\" + textName))
            {
                //readerText.Close();
                readerText = new StreamReader(gamePath + "\\" + textName);

            }
            else
            {
                MessageBox.Show("打开失败！", "咳咳！");
                return;
            }

            //初始化
            AllClear();
            listBox1.Items.Clear();
            gameList = new List<gameInfoStruct>();
            gameInfoStruct = new gameInfoStruct();
            gameDirStruct = new gameDirStruct();
            gameDel = new List<gameInfoStruct>();


            //显示目录地址到label2
            gameDirPath = gamePath;
            label2.Text = gameDirPath;

            //定义函数line用来存放每一行文本
            string line;
            //定义一个开关a，一旦第一次读取到launch行，则a变成1
            var a = 0;
            //定义一个临时函数，用来累加存放每一行ignore-files文本
            var tIgnoreFile = "";
            var tFile = "";
            //循环遍历txt文件
            while (!readerText.EndOfStream)
            {
                //把当前行存入line，每循环一次，ReadLine()就会自己跳到下一行
                line = readerText.ReadLine();
                //把当前行按“:”进行分割，存入数组tt
                char[] separator = {':'};
                //separator必须是字符数组时，2才表示最大只分割出2个子数组
                string[] tt = line.Split(separator, 2);
                //如果a为0，说明读取的是文件头
                if (a == 0)
                {
                    //tt[0]是“:”之前的字段，把tt[1]存入相应的字段
                    switch (tt[0])
                    {
                        case "collection":
                            gameDirStruct.collection = tt[1];
                            break;
                        case "sort-by":
                            gameDirStruct.sortBy = tt[1];
                            break;
                        case "extensions":
                            gameDirStruct.extensions = tt[1];
                            break;
                        case "ignore-files":
                            break;
                        case "launch":
                            gameDirStruct.launch = tt[1];
                            // 第一次读取到launch行，说明游戏信息已经读完，a赋值为1
                            a = 1;
                            break;
                        default:
                            //没有冒号且不为空的行即为ignore-files的数据，用tIgnoreFile来进行累加
                            if (line != "") tIgnoreFile = tIgnoreFile + line + '|';
                            break;
                    }
                }
                //如果a不为0，说明读取到了游戏信息行。
                else
                {
                    switch (tt[0])
                    {
                        case "game":
                            //新的开始，初始化
                            gameInfoStruct = new gameInfoStruct();
                            tFile = "";
                            // 暂定mediaType = 0
                            gameInfoStruct.mediaType = 0;
                            gameInfoStruct.game = tt[1];
                            break;
                        case "sort-by":
                            gameInfoStruct.sortBy = tt[1];
                            break;
                        case "file":
                            gameInfoStruct.file = tt[1];
                            break;
                        case "files":
                            // 如果读取到files标签，说明file为双行，fileType = 1
                            gameInfoStruct.fileType = 1;
                            break;
                        case "developer":
                            gameInfoStruct.developer = tt[1];
                            break;
                        case "genre":
                            gameInfoStruct.genre = tt[1];
                            break;
                        case "publisher":
                            gameInfoStruct.publisher = tt[1];
                            break;
                        case "x-id":
                            gameInfoStruct.xID = tt[1];
                            break;
                        case "assets.box_front":
                            gameInfoStruct.box = tt[1];
                            break;
                        case "assets.logo":
                            gameInfoStruct.logo = tt[1];
                            break;
                        case "assets.video":
                            gameInfoStruct.video = tt[1];
                            break;
                        case "launch":
                            gameInfoStruct.launch = tt[1];
                            break;
                        case "description":
                            gameInfoStruct.description = tt[1];
                            if (gameInfoStruct.fileType == 1)
                            {
                                // fileType = 1，即多行file时，把累加的tFile赋值给files，并去掉最末尾的换行
                                gameInfoStruct.files = tFile.TrimEnd('\n');
                                // 同时判断多行时，media文件夹中是否有以game命名的文件夹，有则mediaType = 2
                                if (Directory.Exists(gameDirPath + "\\media\\" + KillLast(gameInfoStruct.game))) gameInfoStruct.mediaType = 2;
                            }
                            else
                            {
                                // 单行file时，判断media中是以rom命名还是以game命名文件夹
                                if (Directory.Exists(gameDirPath + "\\media\\" + KillLast(gameInfoStruct.file)))
                                {
                                    // media中有以rom命名的文件，则mediaType = 1；
                                    gameInfoStruct.mediaType = 1;
                                }
                                else 
                                {
                                    // media中有以game命名的文件，则mediaType = 2； 
                                    if (Directory.Exists(gameDirPath + "\\media\\" + KillLast(gameInfoStruct.game))) gameInfoStruct.mediaType = 2; 
                                }
                            }

                            //把整个gameInfoStruct添加到gameList
                            gameList.Add(gameInfoStruct);
                            break;
                        default:
                            //没有冒号且不为空的行即为Files的数据，用tFile来进行累加
                            if (line != "" && gameInfoStruct.fileType == 1) tFile = tFile + line + "\n";
                            break;
                    }

                }
            }
            // 关闭readrText
            readerText.Close();

            // 把tIgnoreFile赋值给gameDirStruct.ignoeFile
            if(tIgnoreFile != "")gameDirStruct.ignoeFile = tIgnoreFile.TrimEnd('|');

            // 显示信息到窗口
            textBox1.Text = gameDirStruct.collection;
            textBox2.Text = gameDirStruct.extensions;
            textBox3.Text = gameDirStruct.sortBy;
            textBox4.Text = gameDirStruct.launch;
            textBox5.Text = gameDirStruct.ignoeFile;

            //把gameList输出到listBox1
            OutToListBox();
            return;
        }

        public void OutToListBox()
        {
            //把gameList输出到listBox1
            AllClear();
            listBox1.Items.Clear();
            for (int i = 0; i < gameList.Count(); i++)
            {
                listBox1.Items.Add(i+1 + "." + gameList[i].game);
            }
            return;
        }

        public void AllClear()
        {
            //初始化
            pictureBox1.Image = null;
            pictureBox2.Image = null;
            axWindowsMediaPlayer1.URL = null;
        }

        public int CopyFile(string dir1)
        {
            //复制文件
            //dir1，要复制的文件的路径已经全名(包括后缀)
            //dir2，目标位置,并指定新的文件名
            //把“/”替换成“\\”
            dir1 = dir1.Replace("/", "\\");
            string dir2 = dir1 + "_备份_" + DateTime.Now.ToFileTime().ToString();
            if (File.Exists(dir1))
            {
                File.Copy(dir1, dir2, true);
            }
            if (File.Exists(dir2))
            {
                return 1;
            }else return 0;
        }

        public String KillLast(string dir) 
        {
            // 去掉文件名后缀
            string redir;
            if (dir.LastIndexOf(".") != -1)
            {
                redir = dir.Substring(0, dir.LastIndexOf(".")).Trim();
            }
            else
            {
                //去掉字符前后空格
                redir = dir.Trim();
            }
            return redir;
        }
        #endregion

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //获取当前选中项从0开始计算的序号，这个序号也是gameList中相应游戏所在的序号
            var i = -1;
            if (listBox1.SelectedIndices.Count - 1 > -1) 
            {
                i = listBox1.SelectedIndices[listBox1.SelectedIndices.Count -1];
            }
            //MessageBox.Show(listBox1.SelectedIndices.Count.ToString()+ "|", "咳咳！");
            if (i > -1)
            {
                //把当前选中的游戏的信息显示出来。
                textBox6.Text = gameList[i].description;
                textBox7.Text = gameList[i].game;
                if (gameList[i].fileType == 1) textBox8.Text = gameList[i].files;
                else textBox8.Text = gameList[i].file;
                textBox9.Text = gameList[i].sortBy;
                textBox10.Text = gameList[i].developer;
                textBox11.Text = gameList[i].box;
                textBox12.Text = gameList[i].logo;
                textBox13.Text = gameList[i].video;
                textBox14.Text = gameList[i].genre;
                textBox15.Text = gameList[i].xID;
                textBox16.Text = gameList[i].launch;

                //显示封面、logo、视频，如果fileType是1，则分段输出，否则直出
                var fp = "";
                var lp = "";
                var vp = "";
                if (gameList[i].fileType == 1)
                {
                    //封面路径
                    if (gameList[i].box != null) fp = gameDirPath + "\\" + gameList[i].box.Trim();
                    //logo路径
                    if (gameList[i].logo != null) lp = gameDirPath + "\\" + gameList[i].logo.Trim();
                    //视频路径
                    if (gameList[i].video != null) vp = gameDirPath + "\\" + gameList[i].video.Trim();
                }
                else
                {
                    string filedir;
                    if (gameList[i].mediaType == 1) 
                    {
                        filedir = KillLast(gameList[i].file);
                    }else filedir = gameList[i].game.Trim();

                    fp = gameDirPath + "\\media\\" + filedir + "\\" + "boxFront.png";
                    // 如果png格式的封面不存在，就读取jpg格式的封面
                    if (!File.Exists(fp)) fp = gameDirPath + "\\media\\" + filedir + "\\" + "boxFront.jpg";
                    lp = gameDirPath + "\\media\\" + filedir + "\\" + "logo.png";
                    if (!File.Exists(lp)) lp = gameDirPath + "\\media\\" + filedir + "\\" + "logo.jpg";
                    vp = gameDirPath + "\\media\\" + filedir + "\\" + "video.mp4";
                    
                }
                //显示封面
                if (File.Exists(fp))
                {
                    FileStream fpStream = new FileStream(fp, FileMode.Open, FileAccess.Read);
                    pictureBox1.Image = Image.FromStream(fpStream);
                    fpStream.Close();
                    fpStream.Dispose();
                }
                else
                {
                    pictureBox1.Image = null;
                }
                //显示logo
                if (File.Exists(lp))
                {
                    FileStream lpStream = new FileStream(lp, FileMode.Open, FileAccess.Read);
                    pictureBox2.Image = Image.FromStream(lpStream);
                    lpStream.Close();
                    lpStream.Dispose();
                }
                else
                {
                    pictureBox2.Image = null;
                }
                //播放视频
                //循环播放
                //axWindowsMediaPlayer1.settings.setMode("loop", true);
                if (File.Exists(vp))
                {
                    axWindowsMediaPlayer1.close();
                    axWindowsMediaPlayer1.URL = vp;
                    axWindowsMediaPlayer1.Ctlcontrols.play();
                }
                else
                {
                    axWindowsMediaPlayer1.close();
                    //axWindowsMediaPlayer1.URL = null;
                }
            }
            else return;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //删除列表按钮

            //删除警告
            //var i = MessageBox.Show("铛铛！\n这是一个一次性按钮，想要再次使用就必须关闭程序再打开！\n要重启程序吗？", "警告[○･｀Д´･ ○]", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            //if (i == DialogResult.OK) 

            //获取当前选中项
            ListBox.SelectedIndexCollection indices = listBox1.SelectedIndices;
            int t = listBox1.SelectedIndex;
            // 遍历删除
            for (int i = indices.Count - 1; i >= 0; i--)
            {
                //把要删的项目添加进删除列表，然后再从gameList移除
                gameDel.Add(gameList[indices[i]]);
                gameList.RemoveAt(indices[i]);
            }

            //把gameList输出到listBox1
            OutToListBox();
            //选择下一个项目
            if(t < listBox1.Items.Count) listBox1.SelectedIndex = t;

        }

        private void button6_Click(object sender, EventArgs e)
        {
            //打开当前目录
            if (Directory.Exists(gameDirPath))
            {
                System.Diagnostics.Process.Start("explorer.exe", gameDirPath);
            }else MessageBox.Show("你还没加载游戏目录呢！", "咳咳！");

        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            //警告
            if (checkBox1.Checked == true) 
            {
                var i = MessageBox.Show("铛铛！\n勾选此项后，删除列表中的游戏时，游戏文件和游戏媒体文件也会被删除，\n请注意保护你的数据哦！\n是否继续？", "警告[○･｀Д´･ ○]", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (i != DialogResult.OK) checkBox1.Checked = false;
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            // 说明按钮
            Form2 settingForm = new Form2();
            settingForm.ShowDialog();
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process.Start("https://space.bilibili.com/186995/");
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {

        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            //警告
            if (checkBox2.Checked == true)
            {
                MessageBox.Show("勾选此项后，metadata.pegasus.txt中的【sort-by:】字段会重新排序，强迫症的最爱！", "咳咳！");
            }
        }
    }
}
